home *** CD-ROM | disk | FTP | other *** search
- Path: news1.h1.usa.pipeline.com!usenet
- From: grantp@usa.pipeline.com(Pete)
- Newsgroups: comp.lang.c++
- Subject: Re: C calling C++ function !!!
- Date: 22 Feb 1996 11:52:13 GMT
- Organization: Kalevi, Inc.
- Message-ID: <4ghldd$rt@news1.usa.pipeline.com>
- NNTP-Posting-Host: pipe7.h1.usa.pipeline.com
- X-PipeUser: grantp
- X-PipeHub: usa.pipeline.com
- X-PipeGCOS: (Pete)
- X-Newsreader: Pipeline USA v3.3.0
-
- On Feb 21, 1996 12:24:45 in article <Re: C calling C++ function !!!>,
- 'a-kovalenko@star.nmb.ru (Alexey Kovalenko)' wrote:
-
-
- >Hello, all.
- >
- >Few days ago Norm Bryar <normanb@halcyon.com> in his answer has written:
- >
- >>Something tells me it's not that simple.
- >>
- >[Skipped]
- >>I believe the accepted thing to do is define a set of 'C' wrapper APIs
- >>that you can export to your 'C' modules. Internally, your wrappers do
- >>class method calls.
- >
- >It's wrong. Function in C++, defined as "C", just uses predefined C
- calling
- >convention instead compiler's preferred.
-
- What? Come again, please.
- >
- >Real solution here (don't say "It will not work" - I'm using this ):
- >
- Well, then you haven't posted all of the relevant code. Even
- "filling the obvious blanks" will not produce workable code without
- and extern "C" somewhere. In particular, the symbol Msg is defined
- in the c++ module, which is referenced in the c code. C++ produces
- a mangled version while the c code looks for _Msg. It won't link.
-
- >Situation : I'm working on project that contain both C and C++ sources and
- I
- >don't want to make C sources C++. I'm needing to call function-classmember
-
- >from C sources . Function must return char* by index(access to indexed
- strings
- >
- >array, fuction in C used instead operator[] in C++).
- >
- >header contains:
- >typedef char * (*MsgFunc)(int iNo );
- >
- >C++ file contains:
- >
- >#include "header.h"
- >#include "cassdef.hpp"
- >
- >static Message * _Msg = new Message("messages.msg");
- >static Message & Msg1 = *_Msg;
- >// Two variables to avoid compiler warning about
- >
- >char * Msg( int iNo )
- >{
- >return Msg1[iNo]; // operator []
- >}
- >
- >MsgFunc Msg = Msg1;
- >
- >And C file contains:
- >
- >#include "header.h"
- >extern MsgFun Msg;
- >{
- >printf( Msg(3) );
- >}
- >
- >So, I'm calling C++ opertaor and class initialises before the "main"
- function.
- >
-
- Even if this did work, it would still be an unacceptable solution to
- most situations. First, the real question was about whether or
- not one can call class member functions from C, the implication
- being that the function being a non-static member requiring the
- caller to furnish the instance to which the member function is
- to be applied. There's no way to do this (portably or using standard
- language features). Alexy's example does not provide for
- specifying the object.
-
- Second, this kind of "hacking" is not acceptable to most project
- supervisors as it creates unmaintanable code. If the intent is
- to call a c++ function from C, the most straightforward way is
- to use an API intermediary. The cost of an extra function call
- is negligible compared with having to pay someone to try to
- figure out what's going on when something goes wrong or there's
- a change to system requirements.
-
- Compare Alexy's "messy" solution with a simple:
-
- extern "C" char * Msg(int);
-
- char * Msg(int i)
- {
- return SomeObject.Msg[i];
- }
-
- Note that the above simple solution still fails the ability to
- specify the object. Code permitting that would be something
- like:
-
- extern "C" char * Msg(void * obj, int i);
-
- char * Msg(void * obj, int i)
- {
- return ((SomeObject*)obj)->Msg(i);
- }
-
- Of course, it's now up to the programmer to ensure that the object
- is of the correct class -- but that's unavoidable if passing
- object pointers to C and back.
-
-
- --
- Pete Grant
- Kalevi, Inc.
- Software Engineering & development
-